PolarFire SoC M-Mode LPDDR4 + minimal SBI runtime#774
Conversation
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds standalone wolfBoot M-mode support for the PolarFire SoC MPFS250T Video Kit, including LPDDR4 bring-up (replacing HSS in the early boot path) and Linux S-mode handoff plumbing.
Changes:
- Enhance SDHCI diagnostics and reliability workarounds (CMD0→CMD8 delay, single-block read option, capability logging).
- Extend RISC-V M-mode boot flow with a reusable M→S handoff API and MPFS-specific “release U54 hart” implementation.
- Introduce MPFS250 DDR/PHY init infrastructure, build-time enablement via
LIBERO_FPGA_CONFIG_DIR, new config template, and CI build job.
Reviewed changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| src/sdhci.c | Adds richer error logging, controller register dump, and reliability workarounds for Cadence SD4HC. |
| src/boot_riscv.c | Adds trap register dump support (regs frame) and factors M→S handoff into overridable helpers. |
| hal/mpfs250.h | Adds MPFS250 peripheral bits and extensive DDRC/PHY register definitions + DDR init declarations. |
| hal/mpfs250.c | Implements MPFS250 DDR/PLL/PHY init, M→S boot on a U54 via IPI handoff, and UART reinit after PLL. |
| docs/Targets.md | Documents new “M-Mode + DDR” configuration and build-time Libero config integration. |
| config/examples/polarfire_mpfs250_m.config | Adds new example config for M-mode + LPDDR4 + SD + S-mode Linux boot. |
| arch.mk | Enables MPFS DDR init when LIBERO_FPGA_CONFIG_DIR is provided (adds -DMPFS_DDR_INIT and include path). |
| .github/workflows/test-configs.yml | Adds CI build job for the new MPFS250 M-mode + DDR config template. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
115db4a to
776474f
Compare
4310c4b to
730fa69
Compare
036fee2 to
21aafa9
Compare
- wolfBoot_fit_memcpy: return int so a failed PDMA copy propagates instead of being swallowed. The weak default (memcpy) returns 0; the MPFS250 PDMA override returns -1 if any chunk's mpfs_pdma_memcpy() fails. Callers now fail closed: fit_load_image_inner returns NULL (kernel load then panics via update_disk.c), the update_disk DTS copy panics, and hal_dts_fixup returns an error on a failed L2->DDR copy-back. - options.mk: gate -DSTACK_SIZE_PER_HART behind RISC-V arch (RISCV/RISCV64). The macro is only consumed by the RISC-V startup asm and the mpfs250-m.ld sed token, so it is no longer emitted for PPC/ARM/other targets. The unconditional default (?= 0) is kept because the linker sed always needs a value to substitute.
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #774
Scan targets checked: wolfboot-bugs, wolfboot-src
Findings: 1
1 finding(s) posted as inline comments (see file-level comments below)
This review was generated automatically by Fenrir. Findings are non-blocking.
| if (regs[A0] >= (unsigned long)MPFS_NUM_HARTS) { | ||
| err = SBI_ERR_INVALID_PARAM; | ||
| } | ||
| else if (sbi_hart_state[regs[A0]] == SBI_HSM_STARTED) { |
There was a problem hiding this comment.
🟠 [Medium] HSM hart_start accepts START_PENDING hart, overwriting pending boot parameters · Concurrency / Race Condition
The SBI_EXT_HSM hart_start handler (line 648) only rejects the call when the target hart is in SBI_HSM_STARTED state. It does not reject SBI_HSM_START_PENDING. Per the SBI v0.2 HSM specification, hart_start must return SBI_ERR_ALREADY_AVAILABLE for any hart that is not in STOPPED state. If a caller issues a second hart_start for the same hart while it is already START_PENDING (e.g., a concurrent or retried call), the else-branch executes: sbi_hart_state[hartid] is written back to START_PENDING (harmless), but sbi_hal_hart_start is called again, which overwrites the pending mailbox entry address and opaque value in DTIM and fires a second MSIP to the target hart. The target hart may already be reading the old mailbox fields mid-boot, so overwriting them races against the target's read of its boot address and opaque data.
Fix: Change the condition from an equality check for STARTED to an inequality check for STOPPED:
else if (sbi_hart_state[regs[A0]] != SBI_HSM_STOPPED) {
err = SBI_ERR_ALREADY_AVAIL;
}This ensures the handler rejects any hart not in the STOPPED state, as required by the SBI v0.2 HSM specification.
Summary
wolfBoot runs standalone in M-mode on the E51 monitor core, replacing both HSS and OpenSBI: it brings up LPDDR4 in software, secure-boots a signed Yocto FIT from SD, and stays resident as a minimal SBI runtime so the U54 cores boot Linux. Result: secure-boot 4-CPU SMP Yocto Linux to a login prompt in ~40 s from power-on, with no Microchip firmware in the boot chain.
Commits
src/ddr_cadence.c+include/ddr_cadence.h; the Microchip PHY/PLL/clock/training and the boardLIBERO_SETTING_*values stay inhal/mpfs250_ddr.c.src/riscv_sbi.c): BASE/TIME/IPI/RFENCE/HSM/DBCN plus the legacy calls, with per-hart M-mode trap stacks,rdtimeand misaligned load/store emulation, atomic cross-hart IPI ops with self-directed SSIP delivery, and the trap-entry / M->S hand-off wiring. PolarFire SoC bring-up adds CLINT MTIME enable, per-hart HSMhart_startmailboxes, the watchdog policy, and the dtb fixups that bring up 4-CPU SMP Linux.Key design points
DDR_CADENCE_CTRL_BASE); the SoC-specific PHY/PLL/training is behind the platform HAL. Both compile only whenMPFS_DDR_INITis set.rdtimeis emulated in M-mode for S and U mode.Validation (MPFS250T Video Kit, power-controlled cold boots)
smp: Brought up 1 node, 4 CPUswith zero "failed to come online"; login at ~40 s.ddr_cadence.o(driver correctly gated).versal_vmk180_sdcard,zynqmp_sdcard,zynq7000_sdcardalso build (shared sdhci/boot files).Notes for reviewers
src/vector_riscv.Strap-macro changes areWOLFBOOT_RISCV_MMODE-gated; S-mode builds keep the original frame behavior.src/sdhci.ckeeps the cross-platform driver clean: the MPFS PDMA/watchdog specifics are behind weaksdhci_platform_block_copy()/sdhci_platform_wdt_pet()hooks.src/fdt.cgains a weakwolfBoot_fit_memcpyhook so the platform can route FIT subimage copies through PDMA.tools/ci/mpfs_libero_stub/fpga_design_config.hlets the M-mode + DDR path compile in GitHub Actions (compile-only; not runnable).lib/wolfsslsubmodule pointer is bumped (came in with the DDR work); drop it if the project prefers to bump separately.docs/Targets.mddocuments the M-mode + DDR Linux boot flow, the wolfSBI runtime, the watchdog policy, and the generic Cadence driver split.